<?php

namespace common\modules\user\models\backend;

use common\modules\user\Module;
use Yii;

/**
 * Class User
 *
 * @package common\modules\user\models\backend
 * @property string|null $password   Password
 * @property string|null $repeat_password Repeat password
 * @property Profile     $profile    Profile
 */
class User extends \common\modules\user\models\User
{

    /**
     * @var array
     */
    static protected $rolesCache;

    /**
     * @var string|null Password
     */
    public $password;

    /**
     * @var string|null Repeat password
     */
    public $repeat_password;

    /**
     * @var string Model status.
     */
    private $_status;

    /**
     * @return string Model status.
     */
    public function getStatus()
    {
        if ($this->_status === null)
        {
            $statuses = self::getStatusArray();
            $this->_status = $statuses[$this->status_id];
        }

        return $this->_status;
    }

    /**
     * @return array
     */
    public function rolesDescription()
    {
        $auth = Yii::$app->authManager;
        if (empty(self::$rolesCache))
        {
            self::$rolesCache = $auth->getRoles();
        }
        $roles = self::$rolesCache;
        $rolesDescription = [];
        if (is_array($this->role))
        {
            foreach ($this->role as $role)
            {
                if (isset($roles[$role]))
                {
                    $rolesDescription[] = "{$roles[$role]->description}<small>({$role})</small>";
                }
            }
        }
        return $rolesDescription;
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            // Required
            [['username', 'email', 'role', 'group_id'], 'required'],
            [['password', 'repeat_password'], 'required', 'on' => ['admin-create']],
            // Trim
            [['username', 'email', 'password', 'repeat_password', 'name', 'surname'], 'trim'],
            // String
            [['password', 'repeat_password'], 'string', 'min' => 6, 'max' => 30],
            // Unique
            [['username', 'email'], 'unique'],
            // Username
            ['username', 'match', 'pattern' => '/^[a-zA-Z0-9_-]+$/'],
            ['username', 'string', 'min' => 3, 'max' => 30],
            // E-mail
            ['email', 'string', 'max' => 100],
            ['email', 'email'],
            // Repassword
            ['repeat_password', 'compare', 'compareAttribute' => 'password'],
            // Role
            ['role', 'filterRoles'],
            // Status
            ['status_id', 'in', 'range' => array_keys(self::getStatusArray())],
        ];
    }

    public function filterRoles($attr)
    {
        $roles = array_keys(self::getRoleArray());
        if ($this->$attr)
        {
            foreach ($this->$attr as $role)
            {
                if ( ! in_array($role, $roles))
                {
                    $this->addError($attr, "Roles are illegal.");

                    return false;
                }
            }
        }
        else
        {
            $this->addError($attr, "Roles can't empty.");
            return false;
        }
        $this->role = join(",", $this->role);

        return true;
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        return [
            'admin-create' => ['username', 'email', 'password', 'repeat_password', 'status_id', 'role'],
            'admin-update' => ['username', 'email', 'password', 'repeat_password', 'status_id', 'role'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        $labels = parent::attributeLabels();

        return array_merge($labels, [
            'password'   => Module::t('user', 'ATTR_PASSWORD'),
            'repeat_password' => Module::t('user', 'ATTR_REPASSWORD'),
        ]);
    }

    /**
     * @inheritdoc
     */
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert))
        {
            if ($this->isNewRecord || ( ! $this->isNewRecord && $this->password))
            {
                $this->setPassword($this->password);
                $this->generateAuthKey();
                $this->generateToken();
            }

            return true;
        }

        return false;
    }

    public function afterFind()
    {
        parent::afterFind();
        if ($this->role)
        {
            $this->role = preg_split("/,/", $this->role);
        }
    }

    /**
     * @inheritdoc
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);

        if ($this->profile !== null)
        {
            $this->profile->save(false);
        }

//        $name = $this->role ? $this->role : self::ROLE_DEFAULT;
        if ($this->role)
        {
            $auth = Yii::$app->authManager;

            if ( ! is_array($this->role))
            {
                $this->role = preg_split("/,/", $this->role);
            }

            if ($this->role)
            {
                if ( ! $insert)
                {
                    $auth->revokeAll($this->id);
                }
                foreach ($this->role as $roleName)
                {
                    $role = $auth->getRole($roleName);
                    $auth->assign($role, $this->id);
                }
            }
        }

    }
}
